package com.ordos.recruit.filter;

import com.ordos.recruit.filter.util.AntPathMatcher;
import com.ordos.recruit.module.user.constant.Conf;
import com.ordos.recruit.module.user.entity.SysSsoUserDto;
import com.ordos.recruit.module.user.helper.SsoTokenLoginHelper;
import com.ordos.recruit.wrapper.RequestHeaderWrapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * app sso filter
 *
 */
public class SsoTokenFilter extends HttpServlet implements Filter {
    private static Logger logger = LoggerFactory.getLogger(SsoTokenFilter.class);

    private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();

    private String logoutPath;
    private String excludedPaths;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        logoutPath = filterConfig.getInitParameter(Conf.SSO_LOGOUT_PATH);
        excludedPaths = filterConfig.getInitParameter(Conf.SSO_EXCLUDED_PATHS);

        logger.info("SsoTokenFilter init.");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        // make url
        String servletPath = req.getServletPath();

        // excluded path check
        if (excludedPaths!=null && !excludedPaths.trim().isEmpty()) {
            for (String excludedPath:excludedPaths.split(",")) {
                String uriPattern = excludedPath.trim();

                // 支持ANT表达式
                if (ANT_PATH_MATCHER.match(uriPattern, servletPath)) {
                    // excluded path, allow
                    chain.doFilter(request, response);
                    return;
                }

            }
        }

        // logout filter
        if (logoutPath!=null
                && !logoutPath.trim().isEmpty()
                && logoutPath.equals(servletPath)) {

            // logout
            SsoTokenLoginHelper.logout(req);

            // response
            res.setStatus(HttpServletResponse.SC_OK);
            res.setContentType("application/json;charset=UTF-8");
            res.getWriter().println("{\"code\":\"SUCCESS\", \"msg\":\"退出成功\"}");

            return;
        }

        // login filter
        SysSsoUserDto ssoUser = SsoTokenLoginHelper.loginCheck(req);
        if (ssoUser == null) {

            // response
            res.setStatus(HttpServletResponse.SC_OK);
            res.setContentType("application/json;charset=UTF-8");
            res.getWriter().println("{\"code\":\"LOGIN_ERROR\", \"msg\":\"访问当前接口, 登录校验失败.\"}");
            return;
        }

        // ser sso user
        request.setAttribute(Conf.SSO_USER, ssoUser);

        ServletRequest requestWrapper = null;

        try {
            String contentType = request.getContentType() == null ? "" : request.getContentType();
            if (StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE)) {
                //重新生成ServletRequest
                requestWrapper = new RequestHeaderWrapper((HttpServletRequest) request);
            }
        } catch (Exception e) {
            res.setStatus(HttpServletResponse.SC_OK);
            res.setContentType("application/json;charset=UTF-8");
            res.getWriter().println("{\"code\":\"ERROR\", \"msg\":\"系统错误, 请联系管理员.\"}");
            return;
        }
        if (requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }


}
